package com.wsy.helloMail.service;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.search.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;

/**
 * @author wangshangyi
 * @version V1.0  2019/10/21 11:52
 */

@Component
public class ReceivedMail {

    @Value("${spring.mail.host}")
    private  String host ;
    @Value("${spring.mail.username}")
    private  String username ;
    @Value("${spring.mail.password}")
    private  String password ;

    /**
     * 连接邮箱并读取邮件
     */
    private Folder getConnect(){
        Properties props = new Properties();
        Session session = Session.getDefaultInstance(props, null);
        //imap才能读文件夹和修改邮件状态，pop3才能使用SearchTerm查找邮件，加密文件夹中邮件无法获取
        try (Store store = session.getStore("pop3")){
            store.connect(host, username, password);
            return store.getFolder("INBOX");
        } catch (MessagingException e) {
            e.printStackTrace();
            return null;
        }

    }

    /**
     * 获取所有邮件
     */
    public Message[] receivedAllMails(Folder folder) throws MessagingException {
        Message message[] = folder.getMessages();
        System.out.println("邮件数量:　" + message.length);
        return message;
    }

    /**
     * 查找符合条件的邮件
     */
    private Message[] searchMail(Folder folder,SearchTerm st) throws MessagingException {
        Message[] message = folder.search(st);
        System.out.println("找到"+message.length+"封符合搜索条件的邮件");
        return message;
    }

    /** 爬工资明细保存到本地
     */
    public void salaryDetails(String filePath) {
        try(Folder folder = getConnect()){
            assert folder != null;
            folder.open(Folder.READ_ONLY);
//            Message[] msgs =receivedAllMails(folder);
            //创建搜索对象
        /*SearchTerm st = new AndTerm(
                new FromStringTerm("*****@****"),
                new SubjectTerm("工资明细")
        );*/
            SearchTerm st = new SubjectTerm("工资明细");
            Message[] msgs = searchMail(folder,st);
            if (msgs.length==0) {
                System.exit(0);
            }
            salaryMailHandle(msgs,filePath);
        } catch (MessagingException | IOException e) {
            e.printStackTrace();
        }
    }

    /** 解析并下载邮件
     *
     * @param msgs 邮件列表
     * @param filePath 下载路径
     * @date  2020/4/18 19:35
     * @author wangshangyi
     */
    private void salaryMailHandle(Message[] msgs,String filePath) throws MessagingException, IOException {
        StringBuilder stringBuilder = new StringBuilder();
        int aaa = 0;
        for (int i = 0; i < msgs.length; i++) {
            Message msg = msgs[i];
            String subject = msg.getSubject();
            /*if (subject == null || !subject.contains("工资")) {
                continue;
            }*/
            String sendTime = formatDate(msg.getSentDate());
            stringBuilder.append("\n发件时间:").append(sendTime);
            stringBuilder.append("\n发件人:").append(formatAddress(msg.getFrom()));
            stringBuilder.append("\n主题：").append(subject);
            if (msg.isMimeType("text/plain")) {
                stringBuilder.append("\t\tContent Type: ").append(msg.getContentType()).append("\nContent:").append(msg.getContent());
            } else if (msg.isMimeType("multipart/*")) {
                Multipart mp = (Multipart) msg.getContent();
                int count = mp.getCount();
//              stringBuilder.append("\t\tContent Type: " + msg.getContentType() + "\n\nA total of " + count + " part");
                for (int j = 0; j < count; j++) {
                    BodyPart bp = mp.getBodyPart(j);
                    String disposition = bp.getDisposition();
                    if (disposition != null && disposition.equals(Part.ATTACHMENT)) {
                        stringBuilder.append("***********************************");
                        stringBuilder.append("附件：").append(bp.getFileName());
                        stringBuilder.append("***********************************");
                    } else {
                        if (bp.isMimeType("text/plain")) {
                            stringBuilder.append("\n-------------------------\n");
                            stringBuilder.append(bp.getContent());
                        }
                    }
                }
            }
            printFile(filePath,sendTime.substring(0, 10) + ".txt", stringBuilder.toString());
            stringBuilder.setLength(0);
            aaa++;
        }
        System.out.println("共爬下来" + aaa + "封工资邮件");
    }

    private  String formatDate(Date date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(
                "yyyy-MM-dd");
        return dateFormat.format(date);
    }

    public  String formatAddress(Address[] addr) {
        StringBuffer sb = new StringBuffer();
        if (addr == null) {
            return "";
        }
        for (int i = 0; i < addr.length; i++) {
            Address a = addr[i];
            if (a instanceof InternetAddress) {
                InternetAddress ia = (InternetAddress) a;
                sb.append(ia.getPersonal() + "<" + ia.getAddress() + ">,");
            } else {
                sb.append(a.toString());
            }
        }
        if (sb.length() != 0) {
            return sb.substring(0, sb.length() - 1);
        }
        return "";
    }

    public  void printFile(String path,String fileName, String content)  {
        File myFile = new File(path, fileName);
        try(FileOutputStream fop = new FileOutputStream(myFile)) {
            byte[] contentInBytes = content.getBytes();
            fop.write(contentInBytes);
            fop.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /** 显示文件夹
     * @date  2020/4/18 19:35
     * @author wangshangyi
     */
    public void showFolders() {

        Properties props = new Properties();
        Session session = Session.getDefaultInstance(props, null);

//        try (Store store= session.getStore("pop3")){
        //imap才能读文件夹,pop3才能使用search查找到邮寄
        try (Store store= session.getStore("imap")){
            store.connect(host, username, password);
            //先获得收件箱，这个文件夹肯定每家的邮箱都有，而且名字很固定
        /*其他文件夹
          Sent Messages
          Drafts
          Junk
          Deleted Messages
          INBOX*/
        /*已删除邮件
          草稿
          INBOX
          已发送
          垃圾邮件*/
            Folder folder = store.getFolder("Deleted Messages");
            folder.open(Folder.READ_ONLY);
            System.out.println(folder.getMessageCount());

            //获取父目录下的所有子目录，这样所有文件夹就都出来了
            Folder[] folders = folder.getParent().list();
            for (Folder f:folders) {
                //打印全名
                System.out.println(f.getFullName());
            }
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }
}